package org.cn.cf.group;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cn.cf.util.CFDefData;
import org.cn.cf.util.CFUtil;


import net.jxta.credential.AuthenticationCredential;
import net.jxta.document.Element;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.document.XMLDocument;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.ID;
import net.jxta.id.IDFactory;
import net.jxta.impl.endpoint.mcast.McastTransport;
import net.jxta.impl.id.UUID.ModuleSpecID;
import net.jxta.impl.loader.RefJxtaLoader;
import net.jxta.impl.membership.passwd.PasswdMembershipService;
import net.jxta.impl.peergroup.StdPeerGroupParamAdv;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.NetPeerGroupFactory;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.PipeService;
import net.jxta.platform.ModuleClassID;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.protocol.PipeAdvertisement;

public class GroupHelper {

	
		private static final Log log = LogFactory.getLog(GroupHelper.class);
	    public static final String PIPE_ID_STR = "BASE_PIPE_ID";
	    public static final String PIPE_NAME_STR = "BASE_PIPE_NAME";
	    public static final String PIPE_TYPE_STR = "BASE_PIPE_TYPE";
	    
	    public static final String PIPE_IN_KEY = "BASE_IN_KEY";
	    public static final String PIPE_OUT_KEY = "BASE_OUT_KEY";

		public PeerGroup createPeerGroup(PeerGroup rootPeerGroup,
				PeerGroupID newPeerGroupID, String groupName, String login,
				String passwd,String description) {
			// create the Peer Group by doing the following:
			// - Create a Peer Group Module Implementation Advertisement and publish
			// it
			// - Create a Peer Group Adv and publish it
			// - Create a Peer Group from the Peer Group Adv and return this object
			PeerGroup satellaPeerGroup = null;
			PeerGroupAdvertisement satellaPeerGroupAdvertisement;
			// Create the PeerGroup Module Implementation Adv
			ModuleImplAdvertisement passwdMembershipModuleImplAdv;
			passwdMembershipModuleImplAdv = this
					.createPasswdMembershipPeerGroupModuleImplAdv(rootPeerGroup);
			// Publish it in the parent peer group
			DiscoveryService rootPeerGroupDiscoveryService = rootPeerGroup
					.getDiscoveryService();
			try {
				rootPeerGroupDiscoveryService.publish(
						passwdMembershipModuleImplAdv, PeerGroup.DEFAULT_LIFETIME,
						PeerGroup.DEFAULT_EXPIRATION);
				rootPeerGroupDiscoveryService
						.remotePublish(passwdMembershipModuleImplAdv,
								PeerGroup.DEFAULT_EXPIRATION);
			} catch (java.io.IOException e) {
				log.error("Can't Publish passwdMembershipModuleImplAdv");
			}
			
			//PeerAdvertisement pa = null;
			
			// Now, Create the Peer Group Advertisement
			satellaPeerGroupAdvertisement = this.createPeerGroupAdvertisement(
					//passwdMembershipModuleImplAdv, 
					
					newPeerGroupID, groupName,
					login, passwd,description);
			
			// Publish it in the parent peer group
			try {
				rootPeerGroupDiscoveryService.publish(
						satellaPeerGroupAdvertisement, PeerGroup.DEFAULT_LIFETIME,
						PeerGroup.DEFAULT_EXPIRATION);
				rootPeerGroupDiscoveryService.remotePublish(
						satellaPeerGroupAdvertisement,

						PeerGroup.DEFAULT_EXPIRATION);
			} catch (java.io.IOException e) {
				log.error("Can't Publish satellaPeerGroupAdvertisement");
			}
			// Finally Create the Peer Group
			if (satellaPeerGroupAdvertisement == null) {
				log.error("satellaPeerGroupAdvertisement is null");
			}
			try {
				//satellaPeerGroupAdvertisement.se
				satellaPeerGroup = rootPeerGroup
						.newGroup(satellaPeerGroupAdvertisement);
			} catch (net.jxta.exception.PeerGroupException e) {
				log.error("Can't create Satella Peer Group from Advertisement");
				return null;
			}
			
			initConPipe(satellaPeerGroup);//初始化基本通讯
			return satellaPeerGroup;
		}

		public PeerGroup createPeerGroup(PeerGroup rootPeerGroup, String groupName,
				String login, String passwd,String description) {

			PeerGroupID netPeerGroupId = IDFactory.newPeerGroupID();
			return createPeerGroup(rootPeerGroup, netPeerGroupId, groupName, login,
					passwd,description);
		}
		
		public PeerGroup createPeerGroup(PeerGroup rootPeerGroup,String id, String groupName,
	           String login, String passwd ,String description){
			PeerGroupID pgId = PeerGroupID.create(URI.create(id));
			return createPeerGroup(rootPeerGroup, pgId, groupName, login,
					passwd,description);
			
		}

		// ��������
		private PeerGroupAdvertisement createPeerGroupAdvertisement(
				//ModuleImplAdvertisement passwdMembershipModuleImplAdv,
				PeerGroupID newPeerGroupID, String groupName, String login,
				String passwd,String description) {
			// Create a PeerGroupAdvertisement for the peer group
			PeerGroupAdvertisement satellaPeerGroupAdvertisement = (PeerGroupAdvertisement) AdvertisementFactory
					.newAdvertisement(PeerGroupAdvertisement.getAdvertisementType());
			
			
			// Instead of creating a new group ID each time, by using the
			// line below
			// satellaPeerGroupAdvertisement.setPeerGroupID
			// (IDFactory.newPeerGroupID());
			// I use a fixed ID so that each time I start PrivatePeerGroup,
			// it creates the same Group
			satellaPeerGroupAdvertisement.setPeerGroupID(newPeerGroupID);
			
//			satellaPeerGroupAdvertisement
//					.setModuleSpecID(passwdMembershipModuleImplAdv
//							.getModuleSpecID());
			
			satellaPeerGroupAdvertisement
			.setModuleSpecID(PeerGroup.allPurposePeerGroupSpecID);
			
			satellaPeerGroupAdvertisement.setName(groupName);
			satellaPeerGroupAdvertisement
					.setDescription(description);
			// Now create the Structured Document Containing the login and
			// passwd informations. Login and passwd are put into the Param
			// section of the peer Group
			if (login != null) {
				
				StructuredTextDocument loginAndPasswd = (StructuredTextDocument) StructuredDocumentFactory
						.newStructuredDocument(new MimeMediaType("text/xml"),
								"Parm");
				String loginAndPasswdString = login + ":"
						+ PasswdMembershipService.makePsswd(passwd) + ":";
				TextElement loginElement = loginAndPasswd.createElement("login",
						loginAndPasswdString);
				loginAndPasswd.appendChild(loginElement);
				
				// All Right, now that loginAndPasswdElement
				// (The strucuted document
				// that is the Param Element for The PeerGroup Adv
				// is done, include it in the Peer Group Advertisement
				
				satellaPeerGroupAdvertisement.putServiceParam(
						PeerGroup.membershipClassID, loginAndPasswd);
				
			    satellaPeerGroupAdvertisement.putServiceParam(PeerGroup.pipeClassID,
			    		CreatBasePipe(newPeerGroupID,groupName+CFDefData.COMBO_SPSTR+"PIPE",PipeService.PropagateType));

			}
			return satellaPeerGroupAdvertisement;
		}
		//加进基础的通信广告
		private Element CreatBasePipe(PeerGroupID pgId,String name,String type){

		    StructuredTextDocument basePipe = (StructuredTextDocument) StructuredDocumentFactory
			.newStructuredDocument(new MimeMediaType("text/xml"),
					"Parm");
		    
		    PipeID pipeID = null;

	        try {
	            pipeID = (PipeID) IDFactory.newPipeID(pgId);
	        } catch (Exception use) {
	            use.printStackTrace();
	        }
	        
		    TextElement IdElement = basePipe.createElement(PIPE_ID_STR,pipeID.toString());
		    TextElement NameElement = basePipe.createElement(PIPE_NAME_STR,name);
		    TextElement TypeElement = basePipe.createElement(PIPE_TYPE_STR,type);
			basePipe.appendChild(IdElement);
			basePipe.appendChild(NameElement);
			basePipe.appendChild(TypeElement);

			return basePipe;
		}

		// �������Ա��¼��������� 
		private ModuleImplAdvertisement createPasswdMembershipPeerGroupModuleImplAdv(
				PeerGroup rootPeerGroup) {
			// Create a ModuleImpl Advertisement for the Passwd
			// Membership Service Take a allPurposePeerGroupImplAdv
			// ModuleImplAdvertisement parameter to
			// Clone some of its fields. It is easier than to recreate
			// everything from scratch
			// Try to locate where the PasswdMembership is within this
			// ModuleImplAdvertisement.
			// For a PeerGroup Module Impl, the list of the services
			// (including Membership) are located in the Param section
			ModuleImplAdvertisement allPurposePeerGroupImplAdv = null;
			try {
				allPurposePeerGroupImplAdv = rootPeerGroup
						.getAllPurposePeerGroupImplAdvertisement();
			} catch (java.lang.Exception e) {
				log.error("Can't Execute: getAllPurposePeerGroupImplAdvertisement();");
			}
			ModuleImplAdvertisement passwdMembershipPeerGroupModuleImplAdv = allPurposePeerGroupImplAdv;
			ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = null;
			StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv = null;
			try {
				passwdMembershipPeerGroupParamAdv = new StdPeerGroupParamAdv(
						allPurposePeerGroupImplAdv.getParam());
			} catch (Exception e) {
				log.error("Can't execute: StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv = new StdPeerGroupParamAdv (allPurposePeerGroupImplAdv.getParam());");
			}

			Hashtable allPurposePeerGroupServicesHashtable = new Hashtable();

			Map<ModuleClassID, Object> map = passwdMembershipPeerGroupParamAdv
					.getServices();
			Set<ModuleClassID> set = map.keySet();
			Iterator iter = set.iterator();
			Object obj;
			while (iter.hasNext()) {
				obj = iter.next();
				allPurposePeerGroupServicesHashtable.put(obj, map.get(obj));
			}

			Enumeration allPurposePeerGroupServicesEnumeration = allPurposePeerGroupServicesHashtable
					.keys();
			boolean membershipServiceFound = false;
			while ((!membershipServiceFound)
					&& (allPurposePeerGroupServicesEnumeration.hasMoreElements())) {
				Object allPurposePeerGroupServiceID = allPurposePeerGroupServicesEnumeration
						.nextElement();
				if (allPurposePeerGroupServiceID
						.equals(PeerGroup.membershipClassID)) {
					// allPurposePeerGroupMemershipServiceModuleImplAdv is
					// the all Purpose Mermbership Service for the all
					// purpose Peer Group Module Impl adv
					ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv = (ModuleImplAdvertisement) allPurposePeerGroupServicesHashtable
							.get(allPurposePeerGroupServiceID);
					// Create the passwdMembershipServiceModuleImplAdv
					passwdMembershipServiceModuleImplAdv = this
							.createPasswdMembershipServiceModuleImplAdv(allPurposePeerGroupMemershipServiceModuleImplAdv);
					// Remove the All purpose Membership Service implementation
					allPurposePeerGroupServicesHashtable
							.remove(allPurposePeerGroupServiceID);
					// And Replace it by the Passwd Membership Service
					// Implementation
					allPurposePeerGroupServicesHashtable.put(
							PeerGroup.membershipClassID,
							passwdMembershipServiceModuleImplAdv);
					membershipServiceFound = true;
					// Now the Service Advertisements are complete. Let's
					// update the passwdMembershipPeerGroupModuleImplAdv by
					// Updating its param
					passwdMembershipPeerGroupModuleImplAdv
							.setParam((Element) passwdMembershipPeerGroupParamAdv
									.getDocument(MimeMediaType.XMLUTF8));
					// Update its Spec ID This comes from the
					// Instant P2P PeerGroupManager Code (Thanks !!!!)
					if (!passwdMembershipPeerGroupModuleImplAdv.getModuleSpecID()
							.equals(PeerGroup.allPurposePeerGroupSpecID)) {
						passwdMembershipPeerGroupModuleImplAdv
								.setModuleSpecID(IDFactory
										.newModuleSpecID(passwdMembershipPeerGroupModuleImplAdv
												.getModuleSpecID().getBaseClass()));
					} else {
						ID passwdGrpModSpecID = ID
								.create(URI
										.create("urn:jxta:uuid-DeadBeefDeafBabaFeedBabe00000001"
												+ "04" + "06"));
						passwdMembershipPeerGroupModuleImplAdv
								.setModuleSpecID((ModuleSpecID) passwdGrpModSpecID);
					} // End Else
					membershipServiceFound = true;
				} // end if (allPurposePeerGroupServiceID.
				// equals(PeerGroup.membershipClassID))
			}// end While
			return passwdMembershipPeerGroupModuleImplAdv;
		}

		// ������Ա��¼������
		private ModuleImplAdvertisement createPasswdMembershipServiceModuleImplAdv(
				ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv) {
			// Create a new ModuleImplAdvertisement for the
			// Membership Service
			ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = (ModuleImplAdvertisement) AdvertisementFactory
					.newAdvertisement(ModuleImplAdvertisement
							.getAdvertisementType());
			passwdMembershipServiceModuleImplAdv
					.setModuleSpecID(PasswdMembershipService.passwordMembershipSpecID);
			passwdMembershipServiceModuleImplAdv
					.setCode(PasswdMembershipService.class.getName());
			passwdMembershipServiceModuleImplAdv
					.setDescription(" Module Impl Advertisement for the PasswdMembership Service");
			passwdMembershipServiceModuleImplAdv
					.setCompat(allPurposePeerGroupMemershipServiceModuleImplAdv
							.getCompat());
			passwdMembershipServiceModuleImplAdv
					.setUri(allPurposePeerGroupMemershipServiceModuleImplAdv
							.getUri());
			passwdMembershipServiceModuleImplAdv
					.setProvider(allPurposePeerGroupMemershipServiceModuleImplAdv
							.getProvider());

			return passwdMembershipServiceModuleImplAdv;
		}


		public PeerGroup getPeerGroup(PeerGroup myNetPeerGroup,
				PeerGroupID satellaPeerGroupID) {
			// First discover the peer group
			// In most cases we should use discovery listeners so that
			// we can do the discovery asynchroneously.
			// Here I won't, for increased simplicity and because
			// The Peer Group Advertisement is in the local cache for sure
			PeerGroup satellaPeerGroup;
			DiscoveryService myNetPeerGroupDiscoveryService = null;
			if (myNetPeerGroup != null) {
				myNetPeerGroupDiscoveryService = myNetPeerGroup
						.getDiscoveryService();
			} else {
				log.error("Can't join Peer Group since it's parent is null");
				System.exit(1);
			}
			boolean isGroupFound = false;
			Enumeration localPeerGroupAdvertisementEnumeration = null;
			PeerGroupAdvertisement satellaPeerGroupAdvertisement = null;
			try {
				localPeerGroupAdvertisementEnumeration = myNetPeerGroupDiscoveryService
						.getLocalAdvertisements(DiscoveryService.GROUP, "GID",
								satellaPeerGroupID.toString());
			} catch (java.io.IOException e) {
				log.error("Can't Discover Local Adv");
			}
			if (localPeerGroupAdvertisementEnumeration != null) {
				while (localPeerGroupAdvertisementEnumeration.hasMoreElements()) {
					PeerGroupAdvertisement pgAdv = null;
					pgAdv = (PeerGroupAdvertisement) localPeerGroupAdvertisementEnumeration
							.nextElement();
					if (pgAdv.getPeerGroupID().equals(satellaPeerGroupID)) {
						satellaPeerGroupAdvertisement = pgAdv;
						isGroupFound = true;
						break;
					}
				}
			}

			try {
				satellaPeerGroup = myNetPeerGroup
						.newGroup(satellaPeerGroupAdvertisement);
			} catch (net.jxta.exception.PeerGroupException e) {
				log.error("Can't create Peer Group from Advertisement");
				e.printStackTrace();
				return null;
			}
			return satellaPeerGroup;
		}

		public ArrayList<PeerGroup> discoverLocalPeerGroup(
				PeerGroup myNetPeerGroup, Map map,ArrayList<PeerGroup> gList) {
			// First discover the peer group
			// In most cases we should use discovery listeners so that
			// we can do the discovery asynchroneously.
			// Here I won't, for increased simplicity and because
			// The Peer Group Advertisement is in the local cache for sure
			//ArrayList<PeerGroup> gList = new ArrayList<PeerGroup>();

			PeerGroup satellaPeerGroup = null;
			DiscoveryService myNetPeerGroupDiscoveryService = null;
			if (myNetPeerGroup != null) {
				myNetPeerGroupDiscoveryService = myNetPeerGroup
						.getDiscoveryService();
			} else {
				log.error("Can't join Peer Group since it's parent is null");
			}
			//boolean isGroupFound = false;
			Enumeration localPeerGroupAdvertisementEnumeration = null;
			PeerGroupAdvertisement satellaPeerGroupAdvertisement = null;
			try {
				localPeerGroupAdvertisementEnumeration = myNetPeerGroupDiscoveryService
						.getLocalAdvertisements(DiscoveryService.GROUP, null,
								null);
			} catch (java.io.IOException e) {
				log.error(e.getMessage());
			}
			if (localPeerGroupAdvertisementEnumeration != null) {
				while (localPeerGroupAdvertisementEnumeration.hasMoreElements()) {
					PeerGroupAdvertisement pgAdv = null;
					pgAdv = (PeerGroupAdvertisement) localPeerGroupAdvertisementEnumeration
							.nextElement();

					log.info(pgAdv.getDocument(MimeMediaType.XMLUTF8).toString());
					String name = pgAdv.getName();
					String descr = pgAdv.getDescription();
					String id = pgAdv.getPeerGroupID().toString();
					
					if (CFUtil.checkConditions(map,name,descr,id)) {
						satellaPeerGroupAdvertisement = pgAdv;
						log.info("find a Advertisement = "
								+ satellaPeerGroupAdvertisement.getDocument(
										MimeMediaType.XMLUTF8).toString());
						try {

							satellaPeerGroup = myNetPeerGroup
									.newGroup(satellaPeerGroupAdvertisement);

						} catch (net.jxta.exception.PeerGroupException e) {
							e.printStackTrace();
						}
						if(satellaPeerGroup!=null){
							gList.add(satellaPeerGroup);
							discoverLocalPeerGroup(satellaPeerGroup,null,gList);
						}
					}
				}
			}

			return gList;
		}

		public void joinPeerGroup(PeerGroup satellaPeerGroup, String login,
				String passwd) {
			// Get the Heavy Weight Paper for the resume
			// Alias define the type of credential to be provided
			StructuredDocument creds = null;
			try {
				// Create the resume to apply for the Job
				// Alias generate the credentials for the Peer Group
				AuthenticationCredential authCred = new AuthenticationCredential(
						satellaPeerGroup, null, creds);
				// Create the resume to apply for the Job
				// Alias generate the credentials for the Peer Group
				MembershipService membershipService = satellaPeerGroup.getMembershipService();
				// Send the resume and get the Job application form
				// Alias get the Authenticator from the Authentication creds

				Authenticator auth = membershipService.apply(authCred);
				// Fill in the Job Application Form
				// Alias complete the authentication
				completeAuth(auth, login, passwd);
				// Check if I got the Job
				// Alias Check if the authentication that was submitted was
				// accepted.
				if (!auth.isReadyForJoin()) {
					log.error("Failure in authentication.");
					log.error("Group was not joined. Does not know how to complete authenticator");
				}
				// I got the Job, Join the company
				// Alias I the authentication I completed was accepted,
				// therefore join the Peer Group accepted.
				membershipService.join(auth);
				
				initConPipe(satellaPeerGroup);//初始化基本通讯
			} catch (Exception e) {
				log.error("Failure in authentication.");
				log.error("Group was not joined. Login was incorrect.");
				e.printStackTrace();
			}
		}
		
		/**
		 * 初始化基本通讯
		 * 创建组或者加入组时必须
		 * 
		 * */
		private boolean initConPipe(PeerGroup satellaPeerGroup){
			/*
			PeerGroupAdvertisement pgAdv = satellaPeerGroup.getPeerGroupAdvertisement();
			StructuredDocument doc = pgAdv.getServiceParam(PeerGroup.pipeClassID);
			TextElement te;
			String id = null;
			String name = "";
			String type = null;
			Enumeration enu =  doc.getChildren(PIPE_ID_STR);
			if(enu.hasMoreElements()){
				te = (TextElement)enu.nextElement();
				id = te.getTextValue();
			}
			enu =  doc.getChildren(PIPE_NAME_STR);
			if(enu.hasMoreElements()){
				te = (TextElement)enu.nextElement();
				name = te.getTextValue();
			}
			
			log.info(satellaPeerGroup.getPeerGroupName()+"组基本通讯信息:id ="+id+" name="+name+" type="+type);
			
			enu =  doc.getChildren(PIPE_TYPE_STR);
			if(enu.hasMoreElements()){
				te = (TextElement)enu.nextElement();
				type = te.getTextValue();
			}
			if(id==null || type==null)
				return false;
		    
			PipeAdvertisement pa = CFUtil.crearePipeAdvertisement(id, type, name);
			PipeService pipsrv = satellaPeerGroup.getPipeService();
			
			OutputPipe output;
			try {
				output = pipsrv.createOutputPipe(pa, 1000);//基础通讯管道

	            IPGResource pgres = (IPGResource)CFResource.getInstance().getJoinPGMap().get(satellaPeerGroup);

	            pgres.getOutputPipes().put(PIPE_OUT_KEY, output);
	        } catch (IOException ex) {
	            log.error(ex.getMessage());
	            return false;
	        }
			
			InputPipe input;
			try {
				//GroupBaseCommListener
				GroupBaseCommListener lstr = new GroupBaseCommListener(satellaPeerGroup,null);
	            input = pipsrv.createInputPipe(pa, lstr);//基础通讯管道
	            IPGResource pgres = (IPGResource)CFResource.getInstance().getJoinPGMap().get(satellaPeerGroup);
	            pgres.getInputPipes().put(PIPE_IN_KEY, input);
	            pgres.getInputListener().put(GroupBaseCommListener.BASE_COMM_KEY, lstr);
	        } catch (IOException ex) {
	            log.error(ex.getMessage());
	            return false;
	        }
	        */
			return true;
		}
		private void completeAuth(Authenticator auth, String login, String passwd)
				throws Exception {

			Method[] methods = auth.getClass().getMethods();
			Vector authMethods = new Vector();
			// Find out with fields of the application needs to be filled
			// Alias Go through the methods of the Authenticator class and
			// copy them sorted by name into a vector.
			for (int eachMethod = 0; eachMethod < methods.length; eachMethod++) {
				if (methods[eachMethod].getName().startsWith("setAuth")) {
					if (Modifier.isPublic(methods[eachMethod].getModifiers())) {
						// sorted insertion.
						for (int doInsert = 0; doInsert <= authMethods.size(); doInsert++) {
							int insertHere = -1;
							if (doInsert == authMethods.size())
								insertHere = doInsert;
							else {
								if (methods[eachMethod].getName().compareTo(
										((Method) authMethods.elementAt(doInsert))
												.getName()) <= 0)
									insertHere = doInsert;
							} // end else
							if (-1 != insertHere) {
								authMethods.insertElementAt(methods[eachMethod],
										insertHere);
								break;
							} // end if ( -1 != insertHere)
						} // end for (int doInsert=0
					} // end if (modifier.isPublic
				} // end if (methods[eachMethod]
			} // end for (int eachMethod)
			Object[] AuthId = { login };
			Object[] AuthPasswd = { passwd };
			for (int eachAuthMethod = 0; eachAuthMethod < authMethods.size(); eachAuthMethod++) {
				Method doingMethod = (Method) authMethods.elementAt(eachAuthMethod);
				String authStepName = doingMethod.getName().substring(7);
				if (doingMethod.getName().equals("setAuth1Identity")) {
					// Found identity Method, providing identity
					doingMethod.invoke(auth, AuthId);
				} else if (doingMethod.getName().equals("setAuth2_Password")) {
					// Found Passwd Method, providing passwd
					doingMethod.invoke(auth, AuthPasswd);
				}
			}
		}
}
